package com.wf.service.articleServiceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wf.dao.mapper.ArchiveMapper;
import com.wf.dao.mapper.ArticleBodyMapper;
import com.wf.dao.mapper.ArticleMapper;
import com.wf.dao.mapper.ArticleTagMapper;
import com.wf.dao.pojo.Article;
import com.wf.dao.pojo.ArticleBody;
import com.wf.dao.pojo.SysUser;
import com.wf.service.*;
import com.wf.utils.UserThreadLocal;
import com.wf.vo.*;
import com.wf.vo.params.ArticleParam;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TagService tagService;
    @Autowired
    private ArchiveMapper archiveMapper;
    @Autowired
    private ArticleTagMapper articleTagMapper;

    @Override
    public Result getArticleList(Integer page, Integer pageSize) {
        //分页查询后返回视图封装对象
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();//可以对这个查询作排序处理
        Page<Article> page1 = new Page<>(page,pageSize);
        Page<Article> articlePage = articleMapper.selectPage(page1, queryWrapper);//根据分页查询条件拿到对应的记录
        List<Article> records = articlePage.getRecords();
        //将分页查询得到的数据封装成 vo 后返回给前端
        List<ArticleVo> list = copyList(records,true,false,true);
        return Result.success(list);
    }

    @Override
    public void deleteArticleById(Integer articleId) {
        articleMapper.deleteById(articleId);
    }

    @Override
    public List<Article> getMyArticleList(int page, int pageSize, int userId) {
        //分页查询后返回视图封装对象
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();//可以对这个查询作排序处理
        queryWrapper.eq("author_id",userId);
        Page<Article> page1 = new Page<>(page,pageSize);
        Page<Article> articlePage = articleMapper.selectPage(page1, queryWrapper);//根据分页查询条件拿到对应的记录
        List<Article> records = articlePage.getRecords();
        return records;
    }


    @Override
    public Result hotArticle() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //order by viewCounts desc
        queryWrapper.orderByDesc(Article::getViewCounts);
        //select id,title
        queryWrapper.select(Article::getId,Article::getTitle);
        //limit 5
        queryWrapper.last("limit " + 5);
        List<Article> articles = articleMapper.selectList(queryWrapper);
        return Result.success(copyList(articles,false,false,true));
    }

    @Override
    public Result newArticle() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //order by viewCounts desc
        queryWrapper.orderByDesc(Article::getCreateDate);
        //select id,title
        queryWrapper.select(Article::getId,Article::getTitle);
        //limit 5
        queryWrapper.last("limit " + 5);
        List<Article> articles = articleMapper.selectList(queryWrapper);
        return Result.success(copyList(articles,false,false,true));
    }

    @Override
    public Result listArchives() {
        return Result.success(archiveMapper.listArchives());
    }

    @Autowired
    private ThreadService threadService;

    @Override
    public Result findArticleById(Integer id) {
        if(id == null){
            return Result.fail(401,"id为null");
        }
        log.info("查询文章:"+id);
        Article article = articleMapper.selectById(id);
        if(article == null){
            log.info("文章id不存在");
            return Result.fail(401,"未查询到该id的文章");
        }
        threadService.updateViewCount(articleMapper,article);
        //文章详情，先暂时不见标签和分类
        return Result.success(copy(article,false,true,true,false));
    }

    @Override
    @Transactional
    public Result publish(ArticleParam articleParam) {
        SysUser sysUser = UserThreadLocal.get();
        Article article = new Article();
        article.setAuthorId(sysUser.getId());
//        article.setCategoryId(articleParam.getCategory().getId());
        article.setCreateDate(System.currentTimeMillis());
        article.setCommentCounts(0);
        article.setSummary(articleParam.getSummary());
        article.setTitle(articleParam.getTitle());
        article.setViewCounts(0);
        article.setWeight(Article.Article_Common);
        log.info("向article中插入一条数据:"+article.toString());
        int articleId = articleMapper.insertArticle(article);
        ArticleBody articleBody = new ArticleBody();
        articleBody.setContent(articleParam.getBody().getContent());
        articleBody.setContentHtml(articleParam.getBody().getContentHtml());
        articleBody.setArticleId(article.getId());
        log.info("向Body中插入一条数据:"+articleBody.toString());
        articleBodyMapper.insert(articleBody);
        article.setBodyId(articleBody.getId());
        log.info("更新article的BodyId:"+article.toString());
        articleMapper.updateById(article);
        ArticleVo articleVo = new ArticleVo();
        articleVo.setId(article.getId());
        return Result.success(articleVo);
    }


    private List<ArticleVo> copyList(List<Article> records, boolean isAuthor, boolean isBody, boolean isTags) {
        List<ArticleVo> articleVoList = new ArrayList<>();
        for (Article article : records) {
            ArticleVo articleVo = copy(article,isAuthor,isBody,isTags);
            articleVoList.add(articleVo);
        }
        return articleVoList;
    }

    private ArticleVo copy(Article article, boolean isAuthor, boolean isBody, boolean isTags) {
        ArticleVo articleVo = new ArticleVo();
        BeanUtils.copyProperties(article, articleVo);
        if (isAuthor) {
            //将昵称设置到 articleVo 中
            SysUser sysUser = sysUserService.findUserById(article.getAuthorId());
            articleVo.setAuthor(sysUser.getNickname());
        }
        //将创建时间设置到 articleVo 中
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
        if (isTags){
            //将其封装为 tagVo 后装入集合，并设置到 articleVo 中
            List<TagVo> tags = tagService.findTagsByArticleId(article.getId());
            articleVo.setTags(tags);
        }
        return articleVo;
    }

    private List<ArticleVo> copyList(List<Article> records, boolean isTag, boolean isAuthor) {
        List<ArticleVo> articleVoList = new ArrayList<>();
        for (Article record : records) {
            articleVoList.add(copy(record,isTag,isAuthor,false,false));
        }
        return articleVoList;
    }

    private List<ArticleVo> copyList(List<Article> records, boolean isTag, boolean isAuthor,boolean isBody,boolean isCategory) {
        List<ArticleVo> articleVoList = new ArrayList<>();
        for (Article record : records) {
            articleVoList.add(copy(record,isTag,isAuthor,isBody,isCategory));
        }
        return articleVoList;
    }

    public ArticleVo copy(Article article, boolean isTag, boolean isAuthor, boolean isBody, boolean isCategory){
        ArticleVo articleVo = new ArticleVo();
        BeanUtils.copyProperties(article,articleVo);
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));

        //并不是所有的接口 都需要标签 作者信息
        if (isTag){
            int articleId = article.getId();
            articleVo.setTags(tagService.findTagsByArticleId(articleId));
            log.info("返回文章详情，设置标签:"+articleVo.getTags());
        }

        if (isAuthor){
            int authorId = article.getAuthorId();
            articleVo.setAuthor(sysUserService.findUserById(authorId).getNickname());
            log.info("返回文章详情，设置作者:"+articleVo.getAuthor());
        }

        if (isBody){
            ArticleBodyVo articleBody = findArticleBody(article.getId());
            articleVo.setBody(articleBody);
            log.info("返回文章详情，设置文章主体:"+articleVo.getId());
        }
        if (isCategory){
            CategoryVo categoryVo = findCategory(article.getCategoryId());
            articleVo.setCategory(categoryVo);
            log.info("返回文章详情，设置类别："+articleVo.getCategory());
        }
        return articleVo;
    }

    @Autowired
    private CategoryService categoryService;

    private CategoryVo findCategory(Integer categoryId) {
        return categoryService.findCategoryById(categoryId);
    }

    @Autowired
    private ArticleBodyMapper articleBodyMapper;

    private ArticleBodyVo findArticleBody(Integer articleId) {
        LambdaQueryWrapper<ArticleBody> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleBody::getArticleId,articleId);
        ArticleBody articleBody = articleBodyMapper.selectOne(queryWrapper);
        ArticleBodyVo articleBodyVo = new ArticleBodyVo();
        articleBodyVo.setContent(articleBody.getContent());
        articleBodyVo.setContentHtml(articleBody.getContentHtml());
        return articleBodyVo;
    }

}
